/**
 * Created by jianglinjie on Mon Oct 09 2017
 * @flow
 */
'use strict';
/* eslint-disable no-unused-vars*/

import type { 
  NetHandler,
  NetRequest,
  NetworkReponse,
  ResponseVerifyResult,
  ErrorHandleResult
} from '../../network';
import ServiceError, { isServiceError } from '../error/ServiceError';
import AuthService from '../auth';
import * as ErrorCode from '../../constants/ErrorCode';

function isValidBody(body: any): boolean {
  if ((typeof body.succeed === 'boolean')
    && (typeof body.errorCode === 'string')
    && (typeof body.msg === 'string')
    && (typeof body.data === 'object')) {
    return true;
  }

  return false;
}

class ServiceNetHandler implements NetHandler {
  async injectExtraURLParam(request: NetRequest): Promise<Object> {
    return {};
  }

  async injectExtraHeaders(request: NetRequest): Promise<Object> {
    let token = await AuthService.getToken();
    if (token) {
      return {
        Authorization: 'Bearer ' + token
      }
    } else {
      return {};
    }
  }

  async verifyResponse(response: NetworkReponse): Promise<ResponseVerifyResult> {
    let body = response.body;
    if (!isValidBody(body)) {
      return {
        error: new ServiceError(ErrorCode.RES_BODY_INVALID, 'body格式不合法'),
        ok: false,
      }
    }

    if (body.succeed) {
      return {
        error: null,
        ok: true,
      }
    } else {
      return {
        error: new ServiceError(body.errorCode, body.msg),
        ok: false,
      }
    }
  }

  async handleError(error: any, request: NetRequest): Promise<ErrorHandleResult> {
    let retry = false;
    try {
      if (isServiceError(error)) {
        if (error.errorCode === ErrorCode.TOKEN_EXPIRE) {
          let succeed = await AuthService.autoLogin();
          if (succeed) {
            //自动登录成功 重试
            retry = true;
          }
        } else if (error.errorCode === ErrorCode.TOKEN_INVALID) {
          await AuthService.logout();
        }
      }
    } catch (error) {
      retry = false;
    }

    return {
      retry: retry,
    }
  }
}

export default new ServiceNetHandler();